<template>
  <div class="app">
    <!-- 右侧设置 -->
    <van-popup
      class="right_setting"
      v-model="rightSetting"
      position="right"
      @close="settingClose"
    >
      <el-form
        ref="form"
        :model="settingForm"
        label-position="top"
        label-width="80px"
      >
        <el-form-item label="asekey：">
          <el-input v-model="settingForm.asekey"></el-input>
        </el-form-item>
        <el-form-item label="aseiv：">
          <el-input v-model="settingForm.aseiv"></el-input>
        </el-form-item>
        <el-button type="primary" @click="rightSetting = false"
          >保存设置</el-button
        >
      </el-form>
    </van-popup>
    <!-- 头部 -->
    <div class="product_head">
      <div class="title">
        <span>酷</span>
        <span>客</span>
        <span>多</span>
        <span>加</span>
        <span>密</span>
        <span>解</span>
        <span>密</span>
        <span>系</span>
        <span>统</span>
      </div>
      <div class="setting_btn" @click="rightSetting = true">
        <i class="el-icon-s-tools"></i>
      </div>
    </div>
    <!-- 操作区域 -->
    <div class="bottom">
      <div class="product_content">
        <div class="left item" :class="{ no_data: !json }">
          <van-empty image="error" description="暂无数据" v-if="!json" />
          <jsonView v-else-if="isJson" :data="json" :font-size="20" />
          <div v-else v-html="json" class="my_html"></div>
        </div>
        <div class="right item">
          <div class="right_box">
            <div class="item desc">
              注意：该加密解密使用的是AES-CBC模式，所需key和iv都为天天果园账号的key和iv
            </div>
            <div class="item">
              <el-input
                type="textarea"
                :autosize="{ minRows: 5, maxRows: 30 }"
                placeholder="请输入需要加密的文本"
                v-model.trim="textarea1"
                class="textarea_input"
                resize="vertical"
              >
              </el-input>
            </div>
            <div class="item">
              <el-input
                type="textarea"
                :autosize="{ minRows: 5, maxRows: 30 }"
                placeholder="请输入需要解密的文本"
                v-model="textarea2"
                class="textarea_input"
              >
              </el-input>
            </div>
            <div class="item">
              <el-button type="primary" class="my_el_button" @click="jiami"
                >加密数据</el-button
              >
              <i></i>
              <el-button type="warning" class="my_el_button" @click="jiemi"
                >解密数据</el-button
              >
            </div>
            <div class="item">
              <el-switch
                v-model="isAuto"
                active-text="开启"
                inactive-text="自动解密"
              >
              </el-switch>
            </div>
            <div class="item">
              <el-button type="text" @click="openApiDebug">
                <span>接口调试</span>
                <i class="el-icon-edit-outline"></i
              ></el-button>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 接口调试区域 -->
    <van-popup
      v-model="isShowApiDebug"
      position="bottom"
      :style="{ height: '80%' }"
      class="api_debug_content"
    >
      <div class="content">
        <div class="top item">
          <el-select
            v-model="axios.method"
            placeholder="请选择"
            style="width: 130px"
          >
            <el-option
              v-for="item in options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
          <el-input
            @input="urlInput"
            v-model="axios.url"
            placeholder="请输入接口地址"
          ></el-input>
          <el-button type="primary" @click="sendAxios">Send</el-button>
        </div>
        <div class="item bottom_content">
          <!-- 参数位置 -->
          <el-tabs v-model="tabKey" v-loading="axiosLoading">
            <el-tab-pane label="Params" name="Params" class="params">
              <el-table
                :data="tableData"
                border
                style="width: 100%"
                ref="tableData"
                @select="tableDataChange(false)"
                @select-all="tableDataChange(false)"
              >
                <el-table-column type="selection" width="55"> </el-table-column>
                <el-table-column label="KEY" width="150">
                  <template slot-scope="scoped">
                    <input
                      placeholder="key"
                      type="text"
                      v-model="scoped.row.key"
                      class="my_no_border_input"
                      @input="
                        keyInput(
                          scoped.$index == tableData.length - 1,
                          scoped.$index,
                          'tableData'
                        )
                      "
                    />
                  </template>
                </el-table-column>
                <el-table-column label="VALUE">
                  <template slot-scope="scoped">
                    <input
                      placeholder="value"
                      type="text"
                      v-model="scoped.row.value"
                      class="my_no_border_input"
                    />
                  </template>
                </el-table-column>
                <el-table-column label="备注" width="250">
                  <template slot-scope="scoped">
                    <input
                      placeholder="desc"
                      type="text"
                      v-model="scoped.row.desc"
                      class="my_no_border_input"
                    />
                  </template>
                </el-table-column>
                <el-table-column label="操作" width="80">
                  <template slot-scope="scoped">
                    <el-button
                      type="text"
                      @click="
                        scoped.$index != tableData.length - 1
                          ? delParams(scoped.$index)
                          : ''
                      "
                      >{{
                        scoped.$index != tableData.length - 1 ? "移除" : "..."
                      }}</el-button
                    >
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="Headers" name="headers" class="params">
              <el-table
                :data="tableData1"
                border
                style="width: 100%"
                ref="tableData1"
              >
                <el-table-column type="selection" width="55"> </el-table-column>
                <el-table-column label="KEY" width="150">
                  <template slot-scope="scoped">
                    <input
                      placeholder="key"
                      type="text"
                      v-model="scoped.row.key"
                      class="my_no_border_input"
                      @input="
                        keyInput(
                          scoped.$index == tableData1.length - 1,
                          scoped.$index,
                          'tableData1'
                        )
                      "
                    />
                  </template>
                </el-table-column>
                <el-table-column label="VALUE">
                  <template slot-scope="scoped">
                    <input
                      placeholder="value"
                      type="text"
                      v-model="scoped.row.value"
                      class="my_no_border_input"
                    />
                  </template>
                </el-table-column>
                <el-table-column label="备注" width="250">
                  <template slot-scope="scoped">
                    <input
                      placeholder="desc"
                      type="text"
                      v-model="scoped.row.desc"
                      class="my_no_border_input"
                    />
                  </template>
                </el-table-column>
                <el-table-column label="操作" width="80">
                  <template slot-scope="scoped">
                    <el-button
                      type="text"
                      @click="
                        scoped.$index != tableData.length - 1
                          ? delParams(scoped.$index)
                          : ''
                      "
                      >{{
                        scoped.$index != tableData.length - 1 ? "移除" : "..."
                      }}</el-button
                    >
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="Body" name="Body">
              <el-input
                type="textarea"
                placeholder="请输入body数据JSON格式"
                v-model="axios.data"
                style="width: 100%; height: 100%; max-height: 100%"
              />
            </el-tab-pane>
            <el-tab-pane label="Response" name="Response">
              <div
                class="msg"
                style="
                  font-size: 13px;
                  color: #bbb;
                  padding-bottom: 15px;
                  text-align: right;
                "
              >
                具体信息可前往控制台Network查看
              </div>
              <el-input
                v-if="response.status == 1"
                type="textarea"
                placeholder="请输入body数据JSON格式"
                v-model="response.content"
                style="width: 100%; height: 100%; max-height: 90%"
              />
              <div
                v-else
                v-html="response.content"
                :class="{ isErr: response.status == 0 }"
              ></div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
      <el-button class="exit" type="text" @click="isShowApiDebug = false">
        关闭</el-button
      >
    </van-popup>
  </div>
</template>

<script>
import jsonView from "vue-json-views";
import utils from "./utils/cryptojs-interface.js";
import Axios from "axios";
export default {
  components: {
    jsonView,
  },
  data() {
    return {
      rightSetting: false,
      settingForm: {
        asekey: "lnlqwynwmolymxnp",
        aseiv: "8628800577744842",
      },
      isAuto: true,
      textarea1: "",
      textarea2: "",
      json: {
        demo: "json格式化",
        arr: [1, 1, 2, 3, 5, 8],
        object: {
          name: "对象",
          age: 25,
          text:
            "注意：该加密解密使用的是AES-CBC模式，所需key和iv都为天天果园账号的key和iv",
        },
      },
      Encrypt: null,
      Decrypt: null,
      isShowApiDebug: false,
      options: [
        {
          value: "post",
          label: "POST",
        },
        {
          value: "get",
          label: "GET",
        },
        {
          value: "update",
          label: "UPDATE",
        },
        {
          value: "delete",
          label: "DELETE",
        },
      ],
      tabKey: "Params",
      tableData: [
        {
          key: "",
          value: "",
          desc: "",
        },
      ],
      tableData1: [
        {
          key: "",
          value: "",
          desc: "",
        },
      ],
      axios: {
        url:
          "http://junyao.api.quxiaozhan.net/OperateService.asmx/GetThreeHomeAdContent?guid=7b33dd14-b183-4d1e-8c96-04baf421498f&v=v1.12.1",
        method: "post",
        data: `{"data":"43675a4f4863466a4a53456a6739446755443266526267644a2b5057754555383455303156576a656e654b6761556654676a6f4c3439356f4271773149517744"}`,
        headers: {},
        params: {},
      },
      axiosLoading: false,
      response: {
        status: 1,
        content: "<h1>response</h1>",
      },
    };
  },
  computed: {
    isJson() {
      return (
        this.s_type(this.json) == "Object" || this.s_type(this.json) == "Array"
      );
    },
  },
  created() {
    let isAuto = localStorage.getItem("isAuto");
    if (isAuto == "true") {
      this.isAuto = true;
    } else {
      this.isAuto = false;
    }
    //
    let { Encrypt, Decrypt } = utils(this.settingForm);
    this.Encrypt = Encrypt;
    this.Decrypt = Decrypt;
    let settingForm = localStorage.getItem("settingForm");
    if (settingForm) this.settingForm = JSON.parse(settingForm);
  },
  mounted() {
    (() => {
      console.clear();
      console.log(
        "%c世界本无BUG %c\n全靠自己研发 --舒榆衡",
        "font-size:20px;font-family:SimHei;color:skyblue;background-color:black;padding: 10px 20px;border-radius:200px;margin:10px 0px 0;border:5px solid #cccccc;",
        "color:#409eff;margin:0 auto;margin:15px 10px 25px;float: right;"
      );
    })();
  },
  methods: {
    openApiDebug() {
      this.isShowApiDebug = true;
      this.$nextTick(() => {
        this.urlInput();
      });
    },
    tableDataChange(flage) {
      let selection = flage ? this.tableData : this.$refs.tableData.selection;
      let path = this.axios.url.split("?")[0];
      let str = "";
      selection.forEach((item, i) => {
        let a = i == 0 ? "?" : "&";
        str += `${a}${item.key}=${item.value}`;
      });
      this.axios.url = path + str.replace(/(\&\=)|(\?\=)/, "");
    },
    urlInput() {
      if (/(\?|\&)$/.test(this.axios.url)) return;
      let objArr = this.axios.url.split(/\?|\&/).splice(1);
      let arr = objArr.map((item) => {
        let [key, value] = item.split("=");
        return {
          key,
          value: value || "",
          desc: "",
        };
      });
      let flage = arr[arr.length - 1].value == "";
      if (!flage) {
        this.tableData = arr;
        this.$nextTick(() => {
          arr.forEach((row, i) => {
            if (i == this.tableData.length - 1) return;
            this.$refs.tableData.toggleRowSelection(row);
          });
        });
        arr.push({
          key: "",
          value: "",
          desc: "",
        });
      }
    },
    sendAxios() {
      if (this.axiosLoading) return;
      this.tabKey = "Response";
      this.axiosLoading = true;
      let { data } = this.axios;
      try {
        data = eval("(" + data + ")");
      } catch (error) {}
      let headers = {};
      let headersData = this.$refs.tableData1.selection.filter(
        (el) => el.key !== ""
      );
      headersData.forEach((item) => {
        headers[item.key] = item.value;
      });
      Axios({
        ...this.axios,
        data: data,
        headers,
      })
        .then(({ data }) => {
          this.response = {
            status: 1,
            content: JSON.stringify(data),
          };
          this.axiosLoading = false;
        })
        .catch((err) => {
          this.axiosLoading = false;
          this.response = {
            status: 0,
            content: err,
          };
        });
    },
    delParams(index) {
      this.tableData.splice(index, 1);
    },
    // keyinput
    keyInput(flage, index, key) {
      if (flage) {
        this[key].push({
          key: "",
          value: "",
          desc: "",
        });
        // 选中
        this.$refs[key].toggleRowSelection(this[key][index]);
      }
    },
    jiami() {
      if (!this.textarea1) return this.$message("加密内容不能为空");
      if (!this.settingForm.asekey || !this.settingForm.aseiv) {
        this.$dialog
          .alert({ title: "加密失败", message: "请填写key和iv" })
          .then(() => {
            this.rightSetting = true;
          });
        return;
      }
      this.textarea2 = this.Encrypt(this.textarea1);
    },
    jiamiCtrlV() {
      if (this.isAuto) {
        this.jiami();
      }
    },
    jiemiCtrlV() {
      if (this.isAuto) {
        this.jiemi();
      }
    },
    jiemi() {
      if (!this.settingForm.asekey || !this.settingForm.aseiv) {
        this.$dialog
          .alert({ title: "解密失败", message: "请填写key和iv" })
          .then(() => {
            this.rightSetting = true;
          });
        return;
      }
      if (!this.textarea2) return (this.textarea1 = "");
      this.textarea1 = this.Decrypt(this.textarea2);
      if (!this.textarea1) this.$message("解密失败或者解密内容为空");
    },
    // 设置触发
    settingClose() {
      let { Encrypt, Decrypt } = utils(this.settingForm);
      this.Encrypt = Encrypt;
      this.Decrypt = Decrypt;
      localStorage.setItem("settingForm", JSON.stringify(this.settingForm));
    },
    s_type(type) {
      return Object.prototype.toString
        .call(type)
        .replace(/\[object (.*)\]/, "$1");
    },
  },
  watch: {
    tableData: {
      handler() {
        this.tableDataChange(true);
      },
      deep: true,
    },
    textarea2() {
      this.jiemiCtrlV();
    },
    isAuto: {
      handler(val) {
        localStorage.setItem("isAuto", val);
      },
      immediate: false,
    },
    textarea1() {
      // this.textarea1 = this.textarea1.replace(" ", "");
      try {
        this.textarea1 = this.textarea1.replace(/[\n\r\t\v\s]/g, "");
        this.json = eval("(" + this.textarea1 + ")");
      } catch (error) {
        this.json = this.textarea1;
      }
    },
  },
};
</script>

<style lang="scss">
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
.app {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  .right_setting {
    height: 100%;
    padding: 15px;
    width: 400px;
    max-width: 60vw;
  }
  .product_head {
    display: flex;
    padding: 20px;
    font-size: 25px;
    font-weight: bold;
    .title {
      letter-spacing: 3px;
      color: #ad4529;
      user-select: none;
      cursor: pointer;
      span {
        transition: all 0.3s;
        transform: translateY(0px);
      }
      span:hover {
        display: inline-block;
        transform: translateY(-8px);
      }
      &::after {
        content: "__shuyuheng";
        font-size: 12px;
        color: #ccc;
        letter-spacing: 0px;
      }
    }
    .setting_btn {
      margin-left: auto;
      cursor: pointer;
      font-size: 25px;
      &:active {
        opacity: 0.4;
      }
    }
  }
  .bottom {
    flex: 1;
    overflow: hidden;
    position: relative;
    .product_content {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      overflow: hidden;
      display: flex;
      .item {
        flex: 1;
        max-height: 100%;
      }
      .left {
        flex: 3;
        background-color: #fff;
        position: relative;
        padding-right: 10px;
        /deep/ .json-view-container {
          background-color: transparent;
          font-size: 20px;
        }
        &.no_data {
          display: flex;
          align-items: center;
          justify-content: center;
        }
        .my_html {
          padding: 35px;
        }
        overflow-y: scroll;
      }
      .right {
        position: relative;
        overflow: visible;
        flex: 1;
        .right_box {
          overflow-y: scroll;
          height: 100%;
        }
        .item {
          margin-bottom: 10px;
          &.desc {
            font-size: 14px;
            color: #666;
            line-height: 1.5;
          }
          .textarea_input {
            .el-textarea__inner {
              // max-height: 300px;
              max-height: 28vh;
              word-break: break-all;
            }
          }
          .my_el_button {
            margin: 5px 3px;
          }
        }
        &::after {
          content: "";
          width: 12px;
          height: 100%;
          position: absolute;
          top: 0;
          left: 0;
          transform: translateX(-100%);
          background-color: white;
          // border-left: 1px solid #ccc;
        }
      }
    }
  }
  .van-overlay {
    z-index: 1800 !important;
  }
  // 接口调试模块
  .api_debug_content {
    padding: 20px;
    display: flex;
    flex-direction: column;
    padding-top: 40px;
    z-index: 1900 !important;
    .content {
      flex: 1;
      display: flex;
      flex-direction: column;
      .top {
        display: flex;
        .el-input__inner,
        .el-button {
          border-radius: 0px;
        }
      }
      .item {
        padding: 8px 0;
        &.bottom_content {
          flex: 1;
          overflow: hidden;
          .el-tabs {
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            position: relative;
            .el-tabs__content {
              flex: 1;
              overflow: hidden;
              .el-tab-pane {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                overflow: hidden;
                overflow-y: auto;
                word-break: break-all; /* 解决英文数字不换行 和英文太长独自换行 */
                textarea {
                  max-height: 100%;
                  height: 100%;
                }
                .isErr {
                  color: red;
                }
              }
            }
          }
        }
      }
      .params {
        .el-table td {
          padding: 0;
          margin: 0;
        }
        .my_no_border_input {
          width: 100%;
          border: none;
          padding: 0 3px;
          background-color: transparent;
          color: black;
          &:focus {
            background-color: #fefefe;
          }
        }
      }
    }
    .exit {
      position: absolute;
      top: 0;
      right: 0;
      transform: translate(-50%, 0);
    }
  }
}
</style>